package com.example.blog_system.security;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.blog_system.dto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtTokenProvider {

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Value("${jwt.expiration}")
    private int jwtExpirationInMs;

    @Autowired
    private TokenBlacklistService tokenBlacklistService;

    public String generateToken(Authentication authentication) {
        UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();

        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);

        try {
            return JWT.create()
                    .withClaim("userId", userPrincipal.getId())
                    .withClaim("username", userPrincipal.getUsername())
                    .withIssuedAt(now)
                    .withExpiresAt(expiryDate)
                    .sign(Algorithm.HMAC256(jwtSecret));
        } catch (JWTCreationException ex) {
            throw new RuntimeException("Error creating JWT token", ex);
        }
    }

    public UserDto getUserFromJWT(String token) {
        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(jwtSecret))
                    .build()
                    .verify(token);
            
            UserDto userDto = new UserDto();
            userDto.setId(decodedJWT.getClaim("userId").asLong());
            userDto.setUsername(decodedJWT.getClaim("username").asString());
            
            return userDto;
        } catch (JWTVerificationException ex) {
            throw new RuntimeException("Invalid JWT token", ex);
        }
    }

    public boolean validateToken(String authToken) {
        try {
            if (tokenBlacklistService.isTokenBlacklisted(authToken)) {
                return false;
            }

            JWT.require(Algorithm.HMAC256(jwtSecret))
                    .build()
                    .verify(authToken);
            return true;
        } catch (JWTVerificationException ex) {
            return false;
        }
    }

    public void invalidateToken(String token) {
        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(jwtSecret))
                    .build()
                    .verify(token);
            
            Date expiryDate = decodedJWT.getExpiresAt();
            tokenBlacklistService.blacklistToken(token, expiryDate.getTime());
        } catch (JWTVerificationException ex) {
        }
    }

    public UserDto getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && 
            authentication.getPrincipal() instanceof UserPrincipal) {
            UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
            UserDto userDto = new UserDto();
            userDto.setId(userPrincipal.getId());
            userDto.setUsername(userPrincipal.getUsername());
            return userDto;
        }
        return null;
    }
}
